#include "app_serial.h"
#include "log.h"

/**
 * @brief : 设置波特率
 * @param    device: 
 * @param    baud_rate: 
 * @return int 
 */
int app_serial_baud(app_device_t *device, SERIAL_BAUD_RATE baud_rate)
{
    /* 声明termios 结构体 */
    struct termios termios_attr;

    /* 通过get方法  获取默认结构体 */
    int ret = tcgetattr(device->dev_fd, &termios_attr);
    if (ret == -1)
    {
        perror("tcgetattr error\n");
        return -1;
    }

    /* 对结构体值进行修改 */
    cfsetspeed(&termios_attr, baud_rate);

    /* 通过set方法  设置结构体 */
    ret = tcsetattr(device->dev_fd, TCSAFLUSH, &termios_attr);

    if (ret == -1)
    {
        perror("tcsetattr error\n");
        return -1;
    }
    return 0;
}

int app_serial_stopbit(app_device_t *device, SERIAL_STOP_BIT stop_bit)
{
    /* 声明termios 结构体 */
    struct termios termios_attr;

    /* 通过get方法  获取默认结构体 */
    int ret = tcgetattr(device->dev_fd, &termios_attr);
    if (ret == -1)
    {
        perror("tcgetattr error\n");
        return -1;
    }

    /* 对结构体进行修改 */
    termios_attr.c_cflag &= ~CSTOPB;/* 清除停止 */
    termios_attr.c_cflag |= stop_bit; /* 设置停止 */

    /* 通过set方法  设置结构体 */
    ret = tcsetattr(device->dev_fd, TCSAFLUSH, &termios_attr);
    if (ret == -1)
    {
        perror("tcsetattr error\n");
        return -1;
    }
    return 0;
}

int app_serial_parity(app_device_t *device, SERAL_PARITY parity)
{
    /* 声明termios 结构体 */
    struct termios termios_attr;

    /* 通过get方法  获取默认结构体 */
    int ret = tcgetattr(device->dev_fd, &termios_attr);
    if (ret == -1)
    {
        perror("tcgetattr error\n");
       return -1;
    }

    /* 对结构体进行修改 */
    termios_attr.c_cflag &= ~(PARENB | PARODD); /* 清除奇偶校验 */
    termios_attr.c_cflag |= parity;   /* 设置校验位 */

    /* 通过set方法  设置结构体 */
    ret = tcsetattr(device->dev_fd, TCSAFLUSH, &termios_attr);

    if (ret == -1)
    {
        perror("tcsetattr error\n");
        return -1;
    }

    return 0;
}

int app_serial_makeraw(app_device_t *device)
{
    /* 声明termios 结构体 */
    struct termios termios_attr;
    /* 通过get方法  获取默认结构体 */
    int ret = tcgetattr(device->dev_fd, &termios_attr);
    if (ret == -1)
    {
        perror("tcgetattr error\n");
        return -1;
    }

    /* 对结构体进行修改 */
    cfmakeraw(&termios_attr);

    /* 通过set方法  设置结构体 */
    ret = tcsetattr(device->dev_fd, TCSAFLUSH, &termios_attr);

    if (ret == -1)
    {
        perror("tcsetattr error\n");
        return -1;
    }
    return 0;
}

/**
 * @brief : 设置阻塞模式
 * @param    device: 
 * @param    isblock: 
 * @return int 
 */
int app_serial_isblock(app_device_t *device, int isblock)
{
    /* 声明termios 结构体 */
    struct termios termios_attr;
    /* 通过get方法  获取默认结构体 */
    int ret = tcgetattr(device->dev_fd, &termios_attr);
    if (ret == -1)
    {
        perror("tcgetattr error\n");
        return -1;
    }

    /* 对结构体进行修改 */
    if(isblock == 1)
    {
        termios_attr.c_cc[VTIME] = 0; /* 无限等待 */
        termios_attr.c_cc[VMIN] = 1;  /* 读取一个字符 */
    }
    else
    {
        termios_attr.c_cc[VTIME] = 2; /* 等待100毫秒 */
        termios_attr.c_cc[VMIN] = 0;  /* 无数据也可返回 */
    }

    /* 通过set方法  设置结构体 */
    ret = tcsetattr(device->dev_fd, TCSAFLUSH, &termios_attr);

    if (ret == -1)
    {
        perror("tcsetattr error\n");
        return -1;
    }
    return 0;
}

/**
 * @brief : 对设备进行串口设置
 * @param    device: 
 * @return int 
 */
int app_serial_init(app_device_t *device)
{
    /* 对设备进行串口设置 */
    int ret = app_serial_baud(device, BR_115200);
    if (ret == -1)
    {
        log_error("app_serial_baud error\n");
        return -1;
    }

    /* 设置校验位 */
    app_serial_stopbit(device, STOP_BIT_1);
    /* 设置停止位 */
    app_serial_parity(device, PARITY_NONE);
    /* 设置原始模式 */
    app_serial_makeraw(device);
    /* 设置阻塞模式 */
    app_serial_isblock(device, 1);
    /* FLASH生效 */
    tcflush(device->dev_fd, TCIOFLUSH);
    return 0;
}